<template>
  <n-grid cols="1 s:1 m:1 l:3 xl:3 2xl:3" responsive="screen" :x-gap="12">
    <n-gi span="1">
      <n-card
        :segmented="{ content: true }"
        :bordered="false"
        class="proCard"
        :style="{ height: `${bodyHeight}px` }"
        size="small"
      >
        <template #header>
          <n-space>
            <n-button type="info" ghost icon-placement="right" @click="AddMenu">
              添加菜单
              <template #icon>
                <div class="flex items-center">
                  <n-icon size="14">
                    <DownOutlined />
                  </n-icon>
                </div>
              </template>
            </n-button>
            <n-button type="info" ghost icon-placement="left" @click="packHandle">
              全部{{ expandedKeys.length ? '收起' : '展开' }}
              <template #icon>
                <div class="flex items-center">
                  <n-icon size="14">
                    <AlignLeftOutlined />
                  </n-icon>
                </div>
              </template>
            </n-button>
          </n-space>
        </template>
        <div class="w-full menu">
          <n-input type="input" v-model:value="pattern" placeholder="输入菜单名称搜索">
            <template #suffix>
              <n-icon size="18" class="cursor-pointer">
                <SearchOutlined />
              </n-icon>
            </template>
          </n-input>
          <div class="py-3 menu-list">
            <template v-if="loading">
              <div class="flex items-center justify-center py-4">
                <n-spin size="medium" />
              </div>
            </template>
            <template v-else>
              <n-tree
                block-line
                cascade
                key-field="menuId"
                label-field="menuTitle"
                :virtual-scroll="true"
                :pattern="pattern"
                :data="treeData"
                :expandedKeys="expandedKeys"
                style="max-height: 650px; overflow: hidden"
                @update:selected-keys="selectedTree"
                @update:expanded-keys="onExpandedKeys"
              />
            </template>
          </div>
        </div>
      </n-card>
    </n-gi>
    <n-gi span="2">
      <n-card
        :segmented="{ content: true }"
        :bordered="false"
        class="proCard"
        :style="{ height: `${bodyHeight}px` }"
        size="small"
      >
        <template #header>
          <n-space>
            <n-icon size="18">
              <FormOutlined />
            </n-icon>
            <span>编辑菜单{{ treeItemTitle ? `：${treeItemTitle}` : '' }}</span>
          </n-space>
        </template>
        <n-alert type="info" closable> 从菜单列表选择一项后，进行编辑</n-alert>
        <n-form
          :model="formParams"
          :rules="rules"
          ref="formRef"
          label-placement="left"
          :label-width="100"
          v-if="isEditMenu"
          class="py-4"
        >
          <n-form-item label="类型" path="type">
            <span>{{ formParams.type === 1 ? '侧边栏菜单' : '' }}</span>
          </n-form-item>
          <n-form-item label="标题" path="menuTitle">
            <n-input placeholder="请输入标题" v-model:value="formParams.menuTitle" />
          </n-form-item>
          <n-form-item label="副标题" path="menuPath">
            <n-input placeholder="请输入副标题" v-model:value="formParams.menuPath" />
          </n-form-item>
          <n-form-item label="组件路径" path="componentPath">
            <n-input placeholder="请输入路径" v-model:value="formParams.componentPath" />
          </n-form-item>
          <n-form-item label="菜单排序" path="menuSort">
            <n-input placeholder="请输入菜单排序" v-model:value="formParams.menuSort" />
          </n-form-item>
          <n-form-item label="打开方式" path="openWay">
            <n-radio-group v-model:value="formParams.openWay" name="openWay">
              <n-space>
                <n-radio value="1">当前窗口</n-radio>
                <n-radio value="2">新窗口</n-radio>
              </n-space>
            </n-radio-group>
          </n-form-item>
          <n-form-item label="菜单权限" path="menuPermissions">
            <n-input
              placeholder="请输入权限，多个权限用，分割"
              v-model:value="formParams.menuPermissions"
            />
          </n-form-item>
          <n-form-item path="auth" style="margin-left: 100px">
            <n-space>
              <n-button type="primary" :loading="subLoading" @click="formSubmit">保存修改</n-button>
              <n-button @click="handleReset">重置</n-button>
              <n-button @click="handleDel">删除</n-button>
            </n-space>
          </n-form-item>
        </n-form>
      </n-card>
    </n-gi>
  </n-grid>
  <CreateDrawer
    ref="createDrawerRef"
    @close="closeCreateDrawer"
    :title="drawerTitle"
    :parentMenuId="parentMenuId"
  />
</template>
<script lang="ts" setup>
import { ref, unref, reactive, onMounted, computed } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { DownOutlined, AlignLeftOutlined, SearchOutlined, FormOutlined } from '@vicons/antd';
import { getMenuList, update, deleteById } from '@/api/system/menu';
import { getTreeItem } from '@/utils';
import CreateDrawer from './CreateDrawer.vue';

import testData from './testData';

const rules = {
  menuTitle: {
    required: true,
    message: '请输入标题',
    trigger: 'blur',
  },
  menuPath: {
    required: true,
    message: '请输入访问路径',
    trigger: 'blur',
  },
};

const formRef: any = ref(null);
const createDrawerRef = ref();
const message = useMessage();
const dialog = useDialog();

let treeItemKey = ref([]);
let parentMenuId = ref(null);

let expandedKeys = ref([]);

const treeData = ref([]);

const loading = ref(true);
const subLoading = ref(false);
const isEditMenu = ref(false);
const treeItemTitle = ref('');
const pattern = ref('');
const drawerTitle = ref('');

const formParams = reactive({
  menuId: '',
  menuTitle: '',
  menuPath: '',
  menuType: '0',
  componentPath: '',
  menuSort: 0,
  openWay: '1',
  menuPermissions: '',
  hidden: false,
});

function AddMenu() {
  drawerTitle.value =
    treeItemTitle.value == '' ? '添加顶栏菜单' : `添加子菜单：${treeItemTitle.value}`;
  openCreateDrawer();
}

function openCreateDrawer() {
  const { openDrawer } = createDrawerRef.value;
  openDrawer();
}

function closeCreateDrawer() {
  loadData();
}

function selectedTree(keys) {
  if (keys.length) {
    const treeItem = getTreeItem(unref(treeData), keys[0], 'menuId');
    parentMenuId.value = keys[0];
    treeItemKey.value = keys;
    treeItemTitle.value = treeItem.menuTitle;
    Object.assign(formParams, treeItem);
    isEditMenu.value = true;
  } else {
    isEditMenu.value = false;
    parentMenuId.value = null;
    treeItemKey.value = [];
    treeItemTitle.value = '';
  }
}

function handleDel() {
  dialog.info({
    title: '提示',
    content: `您确定想删除此权限吗?`,
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      deleteById(treeItemKey.value[0]).then((res) => {
        if (res.success) {
          message.success('删除成功');

          isEditMenu.value = false;
          parentMenuId.value = null;
          treeItemKey.value = [];
          treeItemTitle.value = '';

          loadData();
        }
      });
    },
    onNegativeClick: () => {
      message.error('已取消');
    },
  });
}

function handleReset() {
  const treeItem = getTreeItem(unref(treeData), treeItemKey.value[0], 'menuId');
  Object.assign(formParams, treeItem);
}

function formSubmit() {
  formRef.value.validate((errors: boolean) => {
    if (!errors) {
      update(formParams).then((res) => {
        if (res.success) {
          message.success('修改成功');
          loadData();
        }
      });
    } else {
      message.error('请填写完整信息');
    }
  });
}

function packHandle() {
  if (expandedKeys.value.length) {
    expandedKeys.value = [];
  } else {
    expandedKeys.value = unref(treeData).map((item: any) => item.menuId as string) as [];
  }
}

async function loadData() {
  const treeMenuList = await getMenuList();

  const keys = treeMenuList.result.map((item) => item.menuId);
  Object.assign(formParams, keys);
  treeData.value = treeMenuList.result;
  loading.value = false;
}

onMounted(() => {
  loadData();
});

function onExpandedKeys(keys) {
  expandedKeys.value = keys;
}
</script>
